package com.share.example.stock.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.utils.ThreadUtil;
import com.share.common.utils.DateUtil;
import com.share.example.stock.mapper.TradeDateMapper;
import com.share.example.stock.model.db.TradeDate;
import com.share.example.stock.service.AkService;
import com.share.example.stock.service.ITradeDateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-07-18
 */
@Slf4j
@Service
public class TradeDateServiceImpl extends ServiceImpl<TradeDateMapper, TradeDate> implements ITradeDateService {
    @Resource
    private TradeDateMapper tradeDateMapper;

    @Autowired
    private AkService akService;

    private Map<String, String> yesterdayMap = new HashMap<>(); //yesterdayMap
    private Map<String, TradeDate> dateMap = new HashMap<>(); //TradeDate
    private List<String> ascList = new LinkedList<>(); //使用倒序date

    @Override
    public Map<String, String> initTradeDate() {
        log.info("正在初始化yesterdayDdscMap");
        Map<String, String> _yesterdayMap = new LinkedHashMap<>();

        Map<String, TradeDate> _dateMap = new LinkedHashMap<>();

        Set<String> _ascList = new TreeSet();

        QueryWrapper<TradeDate> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT  date,skip_codes");//使用倒序
        wrapper.orderByAsc("date");//按时间排序

        List<TradeDate> tmpList = tradeDateMapper.selectList(wrapper);
        int size = tmpList.size();
        if (size < 10) {
            log.error("TradeDate表未初始化,请初始化");
        }

        //从小到大的排序
        for (int i = 1; i < size; i++) {
            TradeDate it = tmpList.get(i);
            _yesterdayMap.put(it.getDate(), tmpList.get(i - 1).getDate());

            _dateMap.put(it.getDate(), it);

            _ascList.add(it.getDate());
        }

        if (_yesterdayMap.size() > 0) {
            this.yesterdayMap = _yesterdayMap;
        }

        if (_dateMap.size() > 0) {
            this.dateMap = _dateMap;
        }

        if (_ascList.size() > 0) {
            //这里的处理与别的地方不一样
            List<String> _tmp = new LinkedList<>();
            _ascList.forEach(e -> _tmp.add(e));
            this.ascList = _tmp;
        }

        //异步线程整理数据,主要是去重,不需要清理
        ThreadUtil.execute(() -> {
            for (int i = 0; i < size; i++) {
                TradeDate tradeDate = tmpList.get(i);
                String skipCodes = tradeDate.getSkipCodes();
                if (StringUtils.isEmpty(skipCodes)) {
                    continue;
                }

                List<String> list = Arrays.asList(skipCodes.split(","));
                Set<String> tmpCodeSet = new TreeSet();
                for (String code : list) {
                    if (!StringUtils.isEmpty(code)) {
                        tmpCodeSet.add(code);
                    }
                }

                //执行数据更细
                if (list.size() != tmpCodeSet.size() && tmpCodeSet.size() > 0) {
                    TradeDate record = new TradeDate();
                    record.setDate(tradeDate.getDate());
                    record.setSkipCodes(String.join(",", tmpCodeSet));
                    tradeDateMapper.updateByDate(record);
                }
            }
        });


        return _yesterdayMap;
    }

    //判断date时候是交易日
    @Override
    public boolean isTradeDay(Date date) {
        String strDate = DateUtil.getDate(date);
        String yes = yesterdayMap.get(strDate);
        if (StringUtils.isEmpty(yes)) {
            return false;
        } else {
            return true;
        }
    }

    //获取上一个交易日,不管当天是否为交易日
    @Override
    public String getYesterday(String date) {
        int index = -1;
        int i = ascList.indexOf(date);
        if (i >= 0) {
            index = i - 1;//取上一天
        } else {
            while (i < 0) {
                date = DateUtil.getDate(date, -1);
                i = ascList.indexOf(date);
            }
            index = i;
        }

        if (index >= 0 && i < ascList.size()) {
            return ascList.get(index);
        } else {
            return null;
        }
    }

    //获取上一个交易日的时间 --- date 可能是周六日
    //queryWrapper.lt（）——小于
    //queryWrapper.le（）——小于等于
    @Override
    public String getHistoryDay(String strDate, int addDay) {
        String yesterday = getYesterday(strDate);
        if (yesterday != null) {
            int i1 = ascList.indexOf(yesterday);
            return ascList.get(addDay + i1 + 1);
        } else {
            return null;
        }
    }

    @Override
    public List<String> downDate() {
        List<TradeDate> insertList = new LinkedList<>();
        Date tradeDate = new Date();

        //2.发起请求
        List<String> list = akService.tool_trade_date_hist_sina();
        for (String item : list) {
            TradeDate record = new TradeDate();
            record.setDate(item);
            record.setCreateTime(tradeDate);
            insertList.add(record);

            if (insertList.size() >= 500) {
                int counti = tradeDateMapper.insertbatch(insertList);
                insertList.clear();
            }
        }

        //2.数据入库
        if (insertList.size() > 0) {
            int counti = tradeDateMapper.insertbatch(insertList);
            insertList.clear();
        }

        //3.数据去重
        int countd = tradeDateMapper.deleteRepeatRetainMinId();

        return list;
    }

    //queryWrapper.lt（）——小于
    //queryWrapper.le（）——小于等于contains
    @Override
    public List<TradeDate> listDateNotContainStartAndEnd(String startDate, String endDate) {
        QueryWrapper<TradeDate> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT  date");//去重
        wrapper.gt("date", startDate);//大于
        wrapper.lt("date", endDate); //小于
        wrapper.orderByAsc("date");
        List<TradeDate> list = tradeDateMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(list)) {
            return new LinkedList<>();
        } else {
            return list;
        }
    }

    //dateList必须在 list日历中
    @Override
    public List<String> listNotInTradeDate(Set<String> dataList) {
        List<String> reList = new LinkedList<>();
        if (CollectionUtils.isEmpty(dataList)) {
            return reList;
        }

        //从小到大排序
        List<String> paramList = new LinkedList<>();
        paramList.addAll(dataList);
        Collections.sort(paramList);

        int startDay = ascList.indexOf(paramList.get(0));
        int endDay = ascList.indexOf(paramList.get(paramList.size() - 1));
        if (startDay < 0 || endDay < 0) {
            log.info("方法入参不符合规定");
        }

        for (int i = startDay; i <= endDay; i++) {
            String date = ascList.get(i);
            if (paramList.contains(date)) {
                //调过
            } else {
                reList.add(date);
            }
        }

        return reList;
    }

    @Override
    public List<String> filterSkipCodesByCode(String code, List<String> emptyDateList) {
        List<String> reList = new LinkedList<>();
        if (CollectionUtils.isEmpty(emptyDateList)) {
            return reList;
        }

        if (StringUtils.isEmpty(code)) {
            return reList;
        }

        for (String date : emptyDateList) {
            TradeDate tradeDate = dateMap.get(date);
            if (tradeDate != null && tradeDate.getSkipCodes() != null && tradeDate.getSkipCodes().contains(code)) {
                continue;
            } else {
                reList.add(date);
            }
        }
        return reList;
    }


}
